package yhao.demo.web.firstWeb.interceptor;

import org.apache.http.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import yhao.demo.service.login.apilist.model.LoginPersonModel;
import yhao.demo.web.firstWeb.config.AuthorityAnnotation;
import yhao.demo.web.firstWeb.config.AuthorityAnnotationEnums;
import yhao.demo.web.firstWeb.constants.WebDemoConstants;
import yhao.infra.apilist.JsonCommonCodeEnum;
import yhao.infra.common.cache.YhaoCache;
import yhao.infra.common.spring.SpringBeanPicker;
import yhao.infra.web.interceptor.ZBaseInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Set;

public class AuthorityInterceptor extends ZBaseInterceptorAdapter {
    private Logger visitLog = LoggerFactory.getLogger(this.getClass());
    private YhaoCache yhaoCache;

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) throws Exception {
        try {
            //仅校验方法级别的Handler
            if (!(handler instanceof HandlerMethod)) {
                return super.preHandle(request, response, handler);
            }
            AuthorityAnnotation auth = getAnnotation((HandlerMethod) handler);

            ResponseBody body = new ResponseBody();
            switch (checkHasAuth(request, auth)) {
                case SUCCESS:
                    return super.preHandle(request, response, handler);
                case NO_AUTH:
                    body.setStatus(HttpStatus.SC_FORBIDDEN);
                    body.setCode(JsonCommonCodeEnum.E0007);
                    printJsonMsg(response, body);
                    return false;
                case INVALID:
                    body.setCode(JsonCommonCodeEnum.E0008);
                    printJsonMsg(response, body);
                    return false;
                default:
                    body.setCode(JsonCommonCodeEnum.E0008);
                    printJsonMsg(response, body);
                    return false;
            }
        } catch (Exception e) {
            visitLog.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 设置注解值
     **/
    private AuthorityAnnotation getAnnotation(HandlerMethod handler) {
        HandlerMethod handlerMethod = handler;
        AuthorityAnnotation annotation =
                handlerMethod.getClass().getAnnotation(AuthorityAnnotation.class);
        AuthorityAnnotation methodAnnotation =
                handlerMethod.getMethod().getAnnotation(AuthorityAnnotation.class);
        return methodAnnotation == null ? annotation : methodAnnotation;
    }

    /**
     * 验证当前用户是否有权限
     *
     * @return
     */
    private AuthCheckResult checkHasAuth(HttpServletRequest request, AuthorityAnnotation auth) {
        //登录的人员数据已经放入session
        LoginPersonModel person = (LoginPersonModel)request.getSession().getAttribute(WebDemoConstants.CURRENT_LOGIN_PERSON);
        //下面做逻辑判断
        if (person!=null) {
            initSessionResource();
            if(auth==null){
                return AuthCheckResult.SUCCESS;
            }
            if(person.isAdmin()){
                return AuthCheckResult.SUCCESS;
            }
            Set<String> authSet = person.getCurrentAuthMap();
            if(authSet!=null){
                for(AuthorityAnnotationEnums authEnum:auth.value()){
                    if(authSet.contains(authEnum.name())){
                        return AuthCheckResult.SUCCESS;
                    }
                }
            }
            return AuthCheckResult.NO_AUTH;
        } else {
            return AuthCheckResult.NO_LOGIN;
        }
    }

    private void initSessionResource() {
        if (yhaoCache == null) {
            yhaoCache = SpringBeanPicker.getBean(YhaoCache.class);
        }
    }

    public enum AuthCheckResult {
        SUCCESS,
        NO_LOGIN,
        NO_AUTH,
        INVALID,
    }
}
